<!DOCTYPE html>
<html lang="en">

<!-- Head tag -->
<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="baidu-site-verification" content="DKi2gJy3XK"/>


        <link rel="shortcut icon" href="/img/favicon.ico">

    <!--Description-->
    
        <meta name="description" content="ZZZXXXCCCWXY999的个人博客，佛系写博客">
    

    <!--Author-->
    
        <meta name="author" content="ZZZXXXCCCWXY999">
    

    <!--Open Graph Title-->
    
        <meta property="og:title" content="泛型相关知识"/>
    

    <!--Open Graph Description-->
    
        <meta property="og:description" content="ZZZXXXCCCWXY999的个人博客，佛系写博客"/>
    

    <!--Open Graph Site Name-->
    <meta property="og:site_name" content="ZZZXXXCCCWXY999的个人博客"/>

    <!--Type page-->
    
        <meta property="og:type" content="article"/>
    

    <!--Page Cover-->
    

    <meta name="twitter:card" content="summary"/>
    

    <!-- Title -->
    
    <title>泛型相关知识 - ZZZXXXCCCWXY999的个人博客</title>

    <!-- Tachyons Core CSS -->
    <link rel="stylesheet" href="/css/tachyons.min.css">
<!--    <link rel="stylesheet" href="https://unpkg.com/tachyons/css/tachyons.min.css">-->

    <!-- Custom Fonts -->
<!--    <link href="/css/font-awesome.min.css" rel="stylesheet" type="text/css">-->
    <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>-->
<!--    <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>-->
    <script src="/js/html5shiv.js"></script>
<!--    <script src="//oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>-->
    <script src="/js/respond.min.js"></script>
    <![endif]-->

    <!-- Custom CSS -->
    
<link rel="stylesheet" href="/css/style.css">


    <!-- Google Analytics -->
    


<meta name="generator" content="Hexo 4.2.0"></head>


<body>

<!-- Main Content -->
<!-- Banner -->
<!-- Banner -->
<div class="w-100 bg-1 ph5-ns ph3 text-light">
    
    <nav class="db dt-l w-100 mw8 center border-box pv3">
        <a class="db dtc-l v-mid link dim w-100 w-25-l tc tl-l mb2 mb0-l white" href="/" title="ZZZXXXCCCWXY999的个人博客">
            <img src="http://www.codeblocq.com/assets/projects/hexo-theme-anodyne/assets/anodyne.svg" class="dib h3" alt="ZZZXXXCCCWXY999的个人博客">
        </a>
        <div class="db dtc-l v-mid w-100 w-75-l tc tr-l">
            
                <a class="link dim f6 f5-l dib mr3 mr4-l white" 
                    href="/" 
                    title="首页">
                    首页
                </a>
            
                <a class="link dim f6 f5-l dib mr3 mr4-l white" 
                    href="/archives" 
                    title="博客列表">
                    博客列表
                </a>
            
                <a class="link dim f6 f5-l dib mr3 mr4-l white" 
                    href="/tags" 
                    title="标签">
                    标签
                </a>
            
                <a class="link dim f6 f5-l dib mr3 mr4-l white" 
                    href="/categories" 
                    title="分类">
                    分类
                </a>
            
                <a class="link dim f6 f5-l dib mr3 mr4-l white" 
                    href="/about" 
                    title="关于">
                    关于
                </a>
            
                <a class="link dim f6 f5-l dib mr3 mr4-l white" 
                    href="/contact" 
                    title="联系">
                    联系
                </a>
            
        </div>
    </nav>

    <!-- Title -->
    <div class="w-100 mw8 center vh-40 dt">
        <div class="dtc v-mid white">
            <h1 class="f1-l f2-m tc tc-m tl-ns">泛型相关知识</h1>
            <p class="f4 fw3 pab-100px tc tc-m tl-ns">2020-04-01</p>
        </div>
    </div>

    <!-- Icon -->
    <div class="relative w-100 mw8 center white dn dn-m db-ns">
        <i class="header-icon fa fa-file-text-o"></i>
    </div>
</div>

<!-- Content -->
<div class="w-100 ph2 ph4-m ph5-l mv5 mv6-l">
    <div class="content">
        <div class="mw8 center">
            <div class="cf">
                <div class="fl w-100 w-70-l mw7 left fw3 lh-copy pr4-ns pr0-m post-content">
                    <!-- Tags Vertical -->
                    
                        <div class="tags-container-vertical">
                            <div class="tags-sub-container">
                                <a class="fw3 ph1 dib" href="/tags/java/">#java</a>
                            </div>
                        </div>
                    

                    <!-- Main Post Content -->
                    <p>摘自：<a href="https://www.jianshu.com/p/986f732ed2f1" target="_blank" rel="noopener">https://www.jianshu.com/p/986f732ed2f1</a><br><a href="https://www.cnblogs.com/coprince/p/8603492.html" target="_blank" rel="noopener">https://www.cnblogs.com/coprince/p/8603492.html</a></p>
<h1 id="1，泛型的定义以及存在意义"><a href="#1，泛型的定义以及存在意义" class="headerlink" title="1，泛型的定义以及存在意义"></a>1，泛型的定义以及存在意义</h1><p>泛型，即“参数化类型”。就是将类型由原来的具体的类型参数化，类似于方法中的变量参数，此时类型也定义成参数形式（可以称之为类型形参），然后在使用/调用时传入具体的类型（类型实参）。<br>例如：GenericClass<T>{}</T></p>
<p>一些常用的泛型类型变量：</p>
<p>E：元素（Element），多用于java集合框架</p>
<p>K：关键字（Key）</p>
<p>N：数字（Number）</p>
<p>T：类型（Type）</p>
<p>V：值（Value）</p>
<h2 id="举一个例子"><a href="#举一个例子" class="headerlink" title="举一个例子"></a>举一个例子</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">List arrayList = <span class="keyword">new</span> ArrayList();</span><br><span class="line">arrayList.add(<span class="string">"aaaa"</span>);</span><br><span class="line">arrayList.add(<span class="number">100</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i&lt; arrayList.size();i++)&#123;</span><br><span class="line">    String item = (String)arrayList.get(i);</span><br><span class="line">    Log.d(<span class="string">"泛型测试"</span>,<span class="string">"item = "</span> + item);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>结果：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String</span><br></pre></td></tr></table></figure>
<p>最终以崩溃结束。。原因如下：<br>ArrayList可以存放任意类型，例子中添加了一个String类型，添加了一个Integer类型，再使用时都以String的方式使用，因此程序崩溃了。为了解决类似这样的问题（在编译阶段就可以解决），泛型应运而生。</p>
<p>我们将第一行声明初始化list的代码更改一下，编译器会在编译阶段就能够帮我们发现类似这样的问题。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; arrayList = <span class="keyword">new</span> ArrayList&lt;String&gt;();</span><br><span class="line">...</span><br><span class="line"><span class="comment">//arrayList.add(100); 在编译阶段，编译器就会报错</span></span><br></pre></td></tr></table></figure>

<h1 id="2-泛型存在的意义："><a href="#2-泛型存在的意义：" class="headerlink" title="2.泛型存在的意义："></a>2.泛型存在的意义：</h1><p>1.适用于多种数据类型执行相同的代码（代码复用）<br>2.泛型中的类型在使用时指定，不需要强制类型转换（类型安全，编译器会检查类型）</p>
<h1 id="3-泛型的特性："><a href="#3-泛型的特性：" class="headerlink" title="3.泛型的特性："></a>3.泛型的特性：</h1><p>泛型只在编译阶段有效。看下面的代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; stringArrayList = <span class="keyword">new</span> ArrayList&lt;String&gt;();</span><br><span class="line">List&lt;Integer&gt; integerArrayList = <span class="keyword">new</span> ArrayList&lt;Integer&gt;();</span><br><span class="line"></span><br><span class="line">Class classStringArrayList = stringArrayList.getClass();</span><br><span class="line">Class classIntegerArrayList = integerArrayList.getClass();</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(classStringArrayList.equals(classIntegerArrayList))&#123;</span><br><span class="line">    Log.d(<span class="string">"泛型测试"</span>,<span class="string">"类型相同"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>输出结果：D/泛型测试: 类型相同。</p>
<p>通过上面的例子可以证明，在编译之后程序会采取去泛型化的措施。也就是说Java中的泛型，只在编译阶段有效。在编译过程中，正确检验泛型结果后，会将泛型的相关信息擦出，并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说，泛型信息不会进入到运行时阶段。</p>
<p>对此总结成一句话：泛型类型在逻辑上看以看成是多个不同的类型，实际上都是相同的基本类型。</p>
<h1 id="4-泛型的使用"><a href="#4-泛型的使用" class="headerlink" title="4. 泛型的使用"></a>4. 泛型的使用</h1><p>泛型有三种使用方式，分别为：泛型类、泛型接口、泛型方法</p>
<h2 id="4-1-泛型类"><a href="#4-1-泛型类" class="headerlink" title="4.1 泛型类"></a>4.1 泛型类</h2><p>泛型类型用于类的定义中，被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口。最典型的就是各种容器类，如：List、Set、Map。</p>
<p>泛型类的最基本写法（这么看可能会有点晕，会在下面的例子中详解）：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> 类名称 &lt;泛型标识：可以随便写任意标识号，标识指定的泛型的类型&gt;</span>&#123;</span><br><span class="line">  <span class="keyword">private</span> 泛型标识 <span class="comment">/*（成员变量类型）*/</span> <span class="keyword">var</span>; </span><br><span class="line">  .....</span><br><span class="line"></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>一个最普通的泛型类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//此处T可以随便写为任意标识，常见的如T、E、K、V等形式的参数常用于表示泛型</span></span><br><span class="line"><span class="comment">//在实例化泛型类时，必须指定T的具体类型</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Generic</span>&lt;<span class="title">T</span>&gt;</span>&#123; </span><br><span class="line">    <span class="comment">//key这个成员变量的类型为T,T的类型由外部指定  </span></span><br><span class="line">    <span class="keyword">private</span> T key;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Generic</span><span class="params">(T key)</span> </span>&#123; <span class="comment">//泛型构造方法形参key的类型也为T，T的类型由外部指定</span></span><br><span class="line">        <span class="keyword">this</span>.key = key;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> T <span class="title">getKey</span><span class="params">()</span></span>&#123; <span class="comment">//泛型方法getKey的返回值类型为T，T的类型由外部指定</span></span><br><span class="line">        <span class="keyword">return</span> key;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//泛型的类型参数只能是类类型（包括自定义类），不能是简单类型</span></span><br><span class="line"><span class="comment">//传入的实参类型需与泛型的类型参数类型相同，即为Integer.</span></span><br><span class="line">Generic&lt;Integer&gt; genericInteger = <span class="keyword">new</span> Generic&lt;Integer&gt;(<span class="number">123456</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//传入的实参类型需与泛型的类型参数类型相同，即为String.</span></span><br><span class="line">Generic&lt;String&gt; genericString = <span class="keyword">new</span> Generic&lt;String&gt;(<span class="string">"key_vlaue"</span>);</span><br><span class="line">Log.d(<span class="string">"泛型测试"</span>,<span class="string">"key is "</span> + genericInteger.getKey());</span><br><span class="line">Log.d(<span class="string">"泛型测试"</span>,<span class="string">"key is "</span> + genericString.getKey());</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">12</span>-<span class="number">27</span> <span class="number">09</span>:<span class="number">20</span>:<span class="number">04.432</span> <span class="number">13063</span>-<span class="number">13063</span>/? D/泛型测试: key is <span class="number">123456</span></span><br><span class="line"><span class="number">12</span>-<span class="number">27</span> <span class="number">09</span>:<span class="number">20</span>:<span class="number">04.432</span> <span class="number">13063</span>-<span class="number">13063</span>/? D/泛型测试: key is key_vlaue</span><br></pre></td></tr></table></figure>
<p>定义的泛型类，就一定要传入泛型类型实参么？并不是这样，在使用泛型的时候如果传入泛型实参，则会根据传入的泛型实参做相应的限制，此时泛型才会起到本应起到的限制作用。如果不传入泛型类型实参的话，在泛型类中使用泛型的方法或成员变量定义的类型可以为任何的类型。</p>
<p>看一个例子：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Generic generic = <span class="keyword">new</span> Generic(<span class="string">"111111"</span>);</span><br><span class="line">Generic generic1 = <span class="keyword">new</span> Generic(<span class="number">4444</span>);</span><br><span class="line">Generic generic2 = <span class="keyword">new</span> Generic(<span class="number">55.55</span>);</span><br><span class="line">Generic generic3 = <span class="keyword">new</span> Generic(<span class="keyword">false</span>);</span><br><span class="line"></span><br><span class="line">Log.d(<span class="string">"泛型测试"</span>,<span class="string">"key is "</span> + generic.getKey());</span><br><span class="line">Log.d(<span class="string">"泛型测试"</span>,<span class="string">"key is "</span> + generic1.getKey());</span><br><span class="line">Log.d(<span class="string">"泛型测试"</span>,<span class="string">"key is "</span> + generic2.getKey());</span><br><span class="line">Log.d(<span class="string">"泛型测试"</span>,<span class="string">"key is "</span> + generic3.getKey());</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">D/泛型测试: key is <span class="number">111111</span></span><br><span class="line">D/泛型测试: key is <span class="number">4444</span></span><br><span class="line">D/泛型测试: key is <span class="number">55.55</span></span><br><span class="line">D/泛型测试: key is <span class="keyword">false</span></span><br></pre></td></tr></table></figure>

<p>注意：</p>
<p>泛型的类型参数只能是类类型，不能是简单类型。<br>不能对确切的泛型类型使用instanceof操作。如下面的操作是非法的，编译时会出错。<br>　　if(ex_num instanceof Generic<Number>){ }</Number></p>
<h2 id="4-2-泛型接口"><a href="#4-2-泛型接口" class="headerlink" title="4.2 泛型接口"></a>4.2 泛型接口</h2><p>泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中，可以看一个例子：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//定义一个泛型接口</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Generator</span>&lt;<span class="title">T</span>&gt; </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> T <span class="title">next</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>当实现泛型接口的类，未传入泛型实参时：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 未传入泛型实参时，与泛型类的定义相同，在声明类的时候，需将泛型的声明也一起加到类中</span></span><br><span class="line"><span class="comment"> * 即：class FruitGenerator&lt;T&gt; implements Generator&lt;T&gt;&#123;</span></span><br><span class="line"><span class="comment"> * 如果不声明泛型，如：class FruitGenerator implements Generator&lt;T&gt;，编译器会报错："Unknown class"</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">FruitGenerator</span>&lt;<span class="title">T</span>&gt; <span class="keyword">implements</span> <span class="title">Generator</span>&lt;<span class="title">T</span>&gt;</span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> T <span class="title">next</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>当实现泛型接口的类，传入泛型实参时：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 传入泛型实参时：</span></span><br><span class="line"><span class="comment"> * 定义一个生产器实现这个接口,虽然我们只创建了一个泛型接口Generator&lt;T&gt;</span></span><br><span class="line"><span class="comment"> * 但是我们可以为T传入无数个实参，形成无数种类型的Generator接口。</span></span><br><span class="line"><span class="comment"> * 在实现类实现泛型接口时，如已将泛型类型传入实参类型，则所有使用泛型的地方都要替换成传入的实参类型</span></span><br><span class="line"><span class="comment"> * 即：Generator&lt;T&gt;，public T next();中的的T都要替换成传入的String类型。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">FruitGenerator</span> <span class="keyword">implements</span> <span class="title">Generator</span>&lt;<span class="title">String</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String[] fruits = <span class="keyword">new</span> String[]&#123;<span class="string">"Apple"</span>, <span class="string">"Banana"</span>, <span class="string">"Pear"</span>&#125;;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">next</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        Random rand = <span class="keyword">new</span> Random();</span><br><span class="line">        <span class="keyword">return</span> fruits[rand.nextInt(<span class="number">3</span>)];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="4-3-泛型通配符"><a href="#4-3-泛型通配符" class="headerlink" title="4.3 泛型通配符"></a>4.3 泛型通配符</h2><p>我们知道Ingeter是Number的一个子类，同时在特性章节中我们也验证过Generic<Ingeter>与Generic<Number>实际上是相同的一种基本类型。那么问题来了，在使用Generic<Number>作为形参的方法中，能否使用Generic<Ingeter>的实例传入呢？在逻辑上类似于Generic<Number>和Generic<Ingeter>是否可以看成具有父子关系的泛型类型呢？</Ingeter></Number></Ingeter></Number></Number></Ingeter></p>
<p>为了弄清楚这个问题，我们使用Generic<T>这个泛型类继续看下面的例子：</T></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">showKeyValue1</span><span class="params">(Generic&lt;Number&gt; obj)</span></span>&#123;</span><br><span class="line">    Log.d(<span class="string">"泛型测试"</span>,<span class="string">"key value is "</span> + obj.getKey());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Generic&lt;Integer&gt; gInteger = <span class="keyword">new</span> Generic&lt;Integer&gt;(<span class="number">123</span>);</span><br><span class="line">Generic&lt;Number&gt; gNumber = <span class="keyword">new</span> Generic&lt;Number&gt;(<span class="number">456</span>);</span><br><span class="line"></span><br><span class="line">showKeyValue(gNumber);</span><br><span class="line"></span><br><span class="line"><span class="comment">// showKeyValue这个方法编译器会为我们报错：Generic&lt;java.lang.Integer&gt; </span></span><br><span class="line"><span class="comment">// cannot be applied to Generic&lt;java.lang.Number&gt;</span></span><br><span class="line"><span class="comment">// showKeyValue(gInteger);</span></span><br></pre></td></tr></table></figure>


<p>通过提示信息我们可以看到Generic<Integer>不能被看作为`Generic<Number>的子类。由此可以看出:同一种泛型可以对应多个版本（因为参数类型是不确定的），不同版本的泛型类实例是不兼容的。</Number></Integer></p>
<p>回到上面的例子，如何解决上面的问题？总不能为了定义一个新的方法来处理Generic<Integer>类型的类，这显然与java中的多台理念相违背。因此我们需要一个在逻辑上可以表示同时是Generic<Integer>和Generic<Number>父类的引用类型。由此类型通配符应运而生。</Number></Integer></Integer></p>
<p>我们可以将上面的方法改一下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">showKeyValue1</span><span class="params">(Generic&lt;?&gt; obj)</span></span>&#123;</span><br><span class="line">    Log.d(<span class="string">"泛型测试"</span>,<span class="string">"key value is "</span> + obj.getKey());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>类型通配符一般是使用？代替具体的类型实参，注意了，此处’？’是类型实参，而不是类型形参 。重要说三遍！此处’？’是类型实参，而不是类型形参 ！ 此处’？’是类型实参，而不是类型形参 ！再直白点的意思就是，此处的？和Number、String、Integer一样都是一种实际的类型，可以把？看成所有类型的父类。是一种真实的类型。</p>
<p>可以解决当具体类型不确定的时候，这个通配符就是 ?  ；当操作类型时，不需要使用类型的具体功能时，只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。</p>
<h2 id="4-4-泛型方法"><a href="#4-4-泛型方法" class="headerlink" title="4.4 泛型方法"></a>4.4 泛型方法</h2><p>在java中,泛型类的定义非常简单，但是泛型方法就比较复杂了。</p>
<p>尤其是我们见到的大多数泛型类中的成员方法也都使用了泛型，有的甚至泛型类中也包含着泛型方法，这样在初学者中非常容易将泛型方法理解错了。<br>泛型类，是在实例化类的时候指明泛型的具体类型；泛型方法，是在调用方法的时候指明泛型的具体类型 。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 泛型方法的基本介绍</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> tClass 传入的泛型实参</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> T 返回值为T类型</span></span><br><span class="line"><span class="comment"> * 说明：</span></span><br><span class="line"><span class="comment"> *     1）public 与 返回值中间&lt;T&gt;非常重要，可以理解为声明此方法为泛型方法。</span></span><br><span class="line"><span class="comment"> *     2）只有声明了&lt;T&gt;的方法才是泛型方法，泛型类中的使用了泛型的成员方法并不是泛型方法。</span></span><br><span class="line"><span class="comment"> *     3）&lt;T&gt;表明该方法将使用泛型类型T，此时才可以在方法中使用泛型类型T。</span></span><br><span class="line"><span class="comment"> *     4）与泛型类的定义一样，此处T可以随便写为任意标识，常见的如T、E、K、V等形式的参数常用于表示泛型。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> &lt;T&gt; <span class="function">T <span class="title">genericMethod</span><span class="params">(Class&lt;T&gt; tClass)</span><span class="keyword">throws</span> InstantiationException ,</span></span><br><span class="line"><span class="function">  IllegalAccessException</span>&#123;</span><br><span class="line">        T instance = tClass.newInstance();</span><br><span class="line">        <span class="keyword">return</span> instance;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<p>Object obj = genericMethod(Class.forName(“com.test.test”));</p>
<h3 id="4-4-1-泛型方法的基本用法"><a href="#4-4-1-泛型方法的基本用法" class="headerlink" title="4.4.1 泛型方法的基本用法"></a>4.4.1 泛型方法的基本用法</h3><p>光看上面的例子有的同学可能依然会非常迷糊，我们再通过一个例子，把我泛型方法再总结一下。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GenericTest</span> </span>&#123;</span><br><span class="line">   <span class="comment">//这个类是个泛型类，在上面已经介绍过</span></span><br><span class="line">   <span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Generic</span>&lt;<span class="title">T</span>&gt;</span>&#123;     </span><br><span class="line">        <span class="keyword">private</span> T key;</span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">public</span> <span class="title">Generic</span><span class="params">(T key)</span> </span>&#123;</span><br><span class="line">            <span class="keyword">this</span>.key = key;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//我想说的其实是这个，虽然在方法中使用了泛型，但是这并不是一个泛型方法。</span></span><br><span class="line">        <span class="comment">//这只是类中一个普通的成员方法，只不过他的返回值是在声明泛型类已经声明过的泛型。</span></span><br><span class="line">        <span class="comment">//所以在这个方法中才可以继续使用 T 这个泛型。</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> T <span class="title">getKey</span><span class="params">()</span></span>&#123;</span><br><span class="line">            <span class="keyword">return</span> key;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 这个方法显然是有问题的，在编译器会给我们提示这样的错误信息"cannot reslove symbol E"</span></span><br><span class="line"><span class="comment">         * 因为在类的声明中并未声明泛型E，所以在使用E做形参和返回值类型时，编译器会无法识别。</span></span><br><span class="line"><span class="comment">        public E setKey(E key)&#123;</span></span><br><span class="line"><span class="comment">             this.key = keu</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/** </span></span><br><span class="line"><span class="comment">     * 这才是一个真正的泛型方法。</span></span><br><span class="line"><span class="comment">     * 首先在public与返回值之间的&lt;T&gt;必不可少，这表明这是一个泛型方法，并且声明了一个泛型T</span></span><br><span class="line"><span class="comment">     * 这个T可以出现在这个泛型方法的任意位置.</span></span><br><span class="line"><span class="comment">     * 泛型的数量也可以为任意多个 </span></span><br><span class="line"><span class="comment">     *    如：public &lt;T,K&gt; K showKeyName(Generic&lt;T&gt; container)&#123;</span></span><br><span class="line"><span class="comment">     *        ...</span></span><br><span class="line"><span class="comment">     *        &#125;</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> &lt;T&gt; <span class="function">T <span class="title">showKeyName</span><span class="params">(Generic&lt;T&gt; container)</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"container key :"</span> + container.getKey());</span><br><span class="line">        <span class="comment">//当然这个例子举的不太合适，只是为了说明泛型方法的特性。</span></span><br><span class="line">        T test = container.getKey();</span><br><span class="line">        <span class="keyword">return</span> test;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//这也不是一个泛型方法，这就是一个普通的方法，只是使用了Generic&lt;Number&gt;这个泛型类做形参而已。</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">showKeyValue1</span><span class="params">(Generic&lt;Number&gt; obj)</span></span>&#123;</span><br><span class="line">        Log.d(<span class="string">"泛型测试"</span>,<span class="string">"key value is "</span> + obj.getKey());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//这也不是一个泛型方法，这也是一个普通的方法，只不过使用了泛型通配符?</span></span><br><span class="line">    <span class="comment">//同时这也印证了泛型通配符章节所描述的，?是一种类型实参，可以看做为Number等所有类的父类</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">showKeyValue2</span><span class="params">(Generic&lt;?&gt; obj)</span></span>&#123;</span><br><span class="line">        Log.d(<span class="string">"泛型测试"</span>,<span class="string">"key value is "</span> + obj.getKey());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">     <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 这个方法是有问题的，编译器会为我们提示错误信息："UnKnown class 'E' "</span></span><br><span class="line"><span class="comment">     * 虽然我们声明了&lt;T&gt;,也表明了这是一个可以处理泛型的类型的泛型方法。</span></span><br><span class="line"><span class="comment">     * 但是只声明了泛型类型T，并未声明泛型类型E，因此编译器并不知道该如何处理E这个类型。</span></span><br><span class="line"><span class="comment">    public &lt;T&gt; T showKeyName(Generic&lt;E&gt; container)&#123;</span></span><br><span class="line"><span class="comment">        ...</span></span><br><span class="line"><span class="comment">    &#125;  </span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 这个方法也是有问题的，编译器会为我们提示错误信息："UnKnown class 'T' "</span></span><br><span class="line"><span class="comment">     * 对于编译器来说T这个类型并未项目中声明过，因此编译也不知道该如何编译这个类。</span></span><br><span class="line"><span class="comment">     * 所以这也不是一个正确的泛型方法声明。</span></span><br><span class="line"><span class="comment">    public void showkey(T genericObj)&#123;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="4-4-2-类中的泛型方法"><a href="#4-4-2-类中的泛型方法" class="headerlink" title="4.4.2 类中的泛型方法"></a>4.4.2 类中的泛型方法</h3><p>当然这并不是泛型方法的全部，泛型方法可以出现杂任何地方和任何场景中使用。但是有一种情况是非常特殊的，当泛型方法出现在泛型类中时，我们再通过一个例子看一下</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GenericFruit</span> </span>&#123;</span><br><span class="line">    <span class="class"><span class="keyword">class</span> <span class="title">Fruit</span></span>&#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">"fruit"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="class"><span class="keyword">class</span> <span class="title">Apple</span> <span class="keyword">extends</span> <span class="title">Fruit</span></span>&#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">"apple"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="class"><span class="keyword">class</span> <span class="title">Person</span></span>&#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">"Person"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="class"><span class="keyword">class</span> <span class="title">GenerateTest</span>&lt;<span class="title">T</span>&gt;</span>&#123;</span><br><span class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">show_1</span><span class="params">(T t)</span></span>&#123;</span><br><span class="line">            System.out.println(t.toString());</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//在泛型类中声明了一个泛型方法，使用泛型E，这种泛型E可以为任意类型。可以类型与T相同，也可以不同。</span></span><br><span class="line">        <span class="comment">//由于泛型方法在声明的时候会声明泛型&lt;E&gt;，因此即使在泛型类中并未声明泛型，编译器也能够正确识别泛型方法中识别的泛型。</span></span><br><span class="line">        <span class="keyword">public</span> &lt;E&gt; <span class="function"><span class="keyword">void</span> <span class="title">show_3</span><span class="params">(E t)</span></span>&#123;</span><br><span class="line">            System.out.println(t.toString());</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//在泛型类中声明了一个泛型方法，使用泛型T，注意这个T是一种全新的类型，可以与泛型类中声明的T不是同一种类型。</span></span><br><span class="line">        <span class="keyword">public</span> &lt;T&gt; <span class="function"><span class="keyword">void</span> <span class="title">show_2</span><span class="params">(T t)</span></span>&#123;</span><br><span class="line">            System.out.println(t.toString());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Apple apple = <span class="keyword">new</span> Apple();</span><br><span class="line">        Person person = <span class="keyword">new</span> Person();</span><br><span class="line"></span><br><span class="line">        GenerateTest&lt;Fruit&gt; generateTest = <span class="keyword">new</span> GenerateTest&lt;Fruit&gt;();</span><br><span class="line">        <span class="comment">//apple是Fruit的子类，所以这里可以</span></span><br><span class="line">        generateTest.show_1(apple);</span><br><span class="line">        <span class="comment">//编译器会报错，因为泛型类型实参指定的是Fruit，而传入的实参类是Person</span></span><br><span class="line">        <span class="comment">//generateTest.show_1(person);</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//使用这两个方法都可以成功</span></span><br><span class="line">        generateTest.show_2(apple);</span><br><span class="line">        generateTest.show_2(person);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//使用这两个方法也都可以成功</span></span><br><span class="line">        generateTest.show_3(apple);</span><br><span class="line">        generateTest.show_3(person);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="4-4-3-泛型方法与可变参数"><a href="#4-4-3-泛型方法与可变参数" class="headerlink" title="4.4.3 泛型方法与可变参数"></a>4.4.3 泛型方法与可变参数</h3><p>再看一个泛型方法和可变参数的例子：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> &lt;T&gt; <span class="function"><span class="keyword">void</span> <span class="title">printMsg</span><span class="params">( T... args)</span></span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(T t : args)&#123;</span><br><span class="line">        Log.d(<span class="string">"泛型测试"</span>,<span class="string">"t is "</span> + t);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">printMsg(<span class="string">"111"</span>,<span class="number">222</span>,<span class="string">"aaaa"</span>,<span class="string">"2323.4"</span>,<span class="number">55.55</span>);</span><br></pre></td></tr></table></figure>
<h3 id="4-4-4-静态方法与泛型"><a href="#4-4-4-静态方法与泛型" class="headerlink" title="4.4.4 静态方法与泛型"></a>4.4.4 静态方法与泛型</h3><p>静态方法有一种情况需要注意一下，那就是在类中的静态方法使用泛型：静态方法无法访问类上定义的泛型；如果静态方法操作的引用数据类型不确定的时候，必须要将泛型定义在方法上。</p>
<p>即：如果静态方法要使用泛型的话，必须将静态方法也定义成泛型方法 。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StaticGenerator</span>&lt;<span class="title">T</span>&gt; </span>&#123;</span><br><span class="line">    ....</span><br><span class="line">    ....</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 如果在类中定义使用泛型的静态方法，需要添加额外的泛型声明（将这个方法定义成泛型方法）</span></span><br><span class="line"><span class="comment">     * 即使静态方法要使用泛型类中已经声明过的泛型也不可以。</span></span><br><span class="line"><span class="comment">     * 如：public static void show(T t)&#123;..&#125;,此时编译器会提示错误信息：</span></span><br><span class="line"><span class="comment">          "StaticGenerator cannot be refrenced from static context"</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; <span class="function"><span class="keyword">void</span> <span class="title">show</span><span class="params">(T t)</span></span>&#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="4-4-5-泛型方法总结"><a href="#4-4-5-泛型方法总结" class="headerlink" title="4.4.5 泛型方法总结"></a>4.4.5 泛型方法总结</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">泛型方法能使方法独立于类而产生变化，以下是一个基本的指导原则：</span><br><span class="line">无论何时，如果你能做到，你就该尽量使用泛型方法。也就是说，如果使用泛型方法将整个类泛型化，</span><br><span class="line">那么就应该使用泛型方法。另外对于一个static的方法而已，无法访问泛型类型的参数。</span><br><span class="line">所以如果static方法要使用泛型能力，就必须使其成为泛型方法。</span><br></pre></td></tr></table></figure>
<h2 id="4-5-泛型上下边界"><a href="#4-5-泛型上下边界" class="headerlink" title="4.5 泛型上下边界"></a>4.5 泛型上下边界</h2><p>在使用泛型的时候，我们还可以为传入的泛型类型实参进行上下边界的限制，如：类型实参只准传入某种类型的父类或某种类型的子类。</p>
<p>为泛型添加上边界，即传入的类型实参必须是指定类型的子类型</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">showKeyValue1</span><span class="params">(Generic&lt;? extends Number&gt; obj)</span></span>&#123;</span><br><span class="line">    Log.d(<span class="string">"泛型测试"</span>,<span class="string">"key value is "</span> + obj.getKey());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">Generic&lt;String&gt; generic1 = <span class="keyword">new</span> Generic&lt;String&gt;(<span class="string">"11111"</span>);</span><br><span class="line">Generic&lt;Integer&gt; generic2 = <span class="keyword">new</span> Generic&lt;Integer&gt;(<span class="number">2222</span>);</span><br><span class="line">Generic&lt;Float&gt; generic3 = <span class="keyword">new</span> Generic&lt;Float&gt;(<span class="number">2.4f</span>);</span><br><span class="line">Generic&lt;Double&gt; generic4 = <span class="keyword">new</span> Generic&lt;Double&gt;(<span class="number">2.56</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//这一行代码编译器会提示错误，因为String类型并不是Number类型的子类</span></span><br><span class="line">showKeyValue1(generic1);</span><br><span class="line"></span><br><span class="line">showKeyValue1(generic2);</span><br><span class="line">showKeyValue1(generic3);</span><br><span class="line">showKeyValue1(generic4);</span><br></pre></td></tr></table></figure>
<p>如果我们把泛型类的定义也改一下:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Generic</span>&lt;<span class="title">T</span> <span class="keyword">extends</span> <span class="title">Number</span>&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">private</span> T key;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Generic</span><span class="params">(T key)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.key = key;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> T <span class="title">getKey</span><span class="params">()</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> key;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//这一行代码也会报错，因为String不是Number的子类</span></span><br><span class="line">Generic&lt;String&gt; generic1 = <span class="keyword">new</span> Generic&lt;String&gt;(<span class="string">"11111"</span>);</span><br></pre></td></tr></table></figure>
<p>再来一个泛型方法的例子：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#x2F;&#x2F;在泛型方法中添加上下边界限制的时候，必须在权限声明与返回值之间的&lt;T&gt;上添加上下边界，即在泛型声明的时候添加</span><br><span class="line">&#x2F;&#x2F;public &lt;T&gt; T showKeyName(Generic&lt;T extends Number&gt; container)，编译器会报错：&quot;Unexpected bound&quot;</span><br><span class="line">public &lt;T extends Number&gt; T showKeyName(Generic&lt;T&gt; container)&#123;</span><br><span class="line">    System.out.println(&quot;container key :&quot; + container.getKey());</span><br><span class="line">    T test &#x3D; container.getKey();</span><br><span class="line">    return test;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>通过上面的两个例子可以看出：泛型的上下边界添加，必须与泛型的声明在一起 。</p>
<h2 id="4-6-关于泛型数组要提一下"><a href="#4-6-关于泛型数组要提一下" class="headerlink" title="4.6 关于泛型数组要提一下"></a>4.6 关于泛型数组要提一下</h2><p>看到了很多文章中都会提起泛型数组，经过查看sun的说明文档，在java中是”不能创建一个确切的泛型类型的数组”的。</p>
<p>也就是说下面的这个例子是不可以的：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;String&gt;[] ls = <span class="keyword">new</span> ArrayList&lt;String&gt;[<span class="number">10</span>];</span><br></pre></td></tr></table></figure>
<p>而使用通配符创建泛型数组是可以的，如下面这个例子：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;?&gt;[] ls = <span class="keyword">new</span> ArrayList&lt;?&gt;[<span class="number">10</span>];</span><br></pre></td></tr></table></figure>
<p>这样也是可以的：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;String&gt;[] ls = <span class="keyword">new</span> ArrayList[<span class="number">10</span>];</span><br></pre></td></tr></table></figure>
<p>下面使用Sun的一篇文档的一个例子来说明这个问题：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">List&lt;String&gt;[] lsa = <span class="keyword">new</span> List&lt;String&gt;[<span class="number">10</span>]; <span class="comment">// Not really allowed.    </span></span><br><span class="line">Object o = lsa;    </span><br><span class="line">Object[] oa = (Object[]) o;    </span><br><span class="line">List&lt;Integer&gt; li = <span class="keyword">new</span> ArrayList&lt;Integer&gt;();    </span><br><span class="line">li.add(<span class="keyword">new</span> Integer(<span class="number">3</span>));    </span><br><span class="line">oa[<span class="number">1</span>] = li; <span class="comment">// Unsound, but passes run time store check    </span></span><br><span class="line">String s = lsa[<span class="number">1</span>].get(<span class="number">0</span>); <span class="comment">// Run-time error: ClassCastException.</span></span><br></pre></td></tr></table></figure>


<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">这种情况下，由于JVM泛型的擦除机制，在运行时JVM是不知道泛型信息的，所以可以给oa[<span class="number">1</span>]赋上一个ArrayList而不会出现异常，</span><br><span class="line"></span><br><span class="line">但是在取出数据的时候却要做一次类型转换，所以就会出现ClassCastException，如果可以进行泛型数组的声明，</span><br><span class="line"></span><br><span class="line">上面说的这种情况在编译期将不会出现任何的警告和错误，只有在运行时才会出错。</span><br><span class="line"></span><br><span class="line">而对泛型数组的声明进行限制，对于这样的情况，可以在编译期提示代码有类型安全问题，比没有任何提示要强很多。</span><br></pre></td></tr></table></figure>


<p>下面采用通配符的方式是被允许的:数组的类型不可以是类型变量，除非是采用通配符的方式，因为对于通配符的方式，最后取出数据是要做显式的类型转换的。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">List&lt;?&gt;[] lsa = <span class="keyword">new</span> List&lt;?&gt;[<span class="number">10</span>]; <span class="comment">// OK, array of unbounded wildcard type.    </span></span><br><span class="line">Object o = lsa;    </span><br><span class="line">Object[] oa = (Object[]) o;    </span><br><span class="line">List&lt;Integer&gt; li = <span class="keyword">new</span> ArrayList&lt;Integer&gt;();    </span><br><span class="line">li.add(<span class="keyword">new</span> Integer(<span class="number">3</span>));    </span><br><span class="line">oa[<span class="number">1</span>] = li; <span class="comment">// Correct.    </span></span><br><span class="line">Integer i = (Integer) lsa[<span class="number">1</span>].get(<span class="number">0</span>); <span class="comment">// OK</span></span><br></pre></td></tr></table></figure>


<h1 id="5-限定泛型类型变量"><a href="#5-限定泛型类型变量" class="headerlink" title="5.限定泛型类型变量"></a>5.限定泛型类型变量</h1><p>1.对类的限定：public class TypeLimitForClass&lt;T extends List &amp; Serializable&gt;{}<br>2.对方法的限定：public static&lt;T extends Comparable<T>&gt;T getMin(T a, T b) {}</T></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Author：Jay On 2019/5/10 16:38</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * Description: 类型变量的限定-方法</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TypeLimitForMethod</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 计算最小值</span></span><br><span class="line"><span class="comment">     * 如果要实现这样的功能就需要对泛型方法的类型做出限定</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="comment">//    private static &lt;T&gt; T getMin(T a, T b) &#123;</span></span><br><span class="line"><span class="comment">//        return (a.compareTo(b) &gt; 0) ? a : b;</span></span><br><span class="line"><span class="comment">//    &#125;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 限定类型使用extends关键字指定</span></span><br><span class="line"><span class="comment">     * 可以使类，接口，类放在前面接口放在后面用&amp;符号分割</span></span><br><span class="line"><span class="comment">     * 例如：&lt;T extends ArrayList &amp; Comparable&lt;T&gt; &amp; Serializable&gt;</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T extends Comparable&lt;T&gt;&gt; <span class="function">T <span class="title">getMin</span><span class="params">(T a, T b)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> (a.compareTo(b) &lt; <span class="number">0</span>) ? a : b;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        System.out.println(TypeLimitForMethod.getMin(<span class="number">2</span>, <span class="number">4</span>));</span><br><span class="line">        System.out.println(TypeLimitForMethod.getMin(<span class="string">"a"</span>, <span class="string">"r"</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Author：Jay On 2019/5/10 17:02</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * Description: 类型变量的限定-类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TypeLimitForClass</span>&lt;<span class="title">T</span> <span class="keyword">extends</span> <span class="title">List</span> &amp; <span class="title">Serializable</span>&gt; </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> T data;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> T <span class="title">getData</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> data;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setData</span><span class="params">(T data)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.data = data;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        ArrayList&lt;String&gt; stringArrayList = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        stringArrayList.add(<span class="string">"A"</span>);</span><br><span class="line">        stringArrayList.add(<span class="string">"B"</span>);</span><br><span class="line">        ArrayList&lt;Integer&gt; integerArrayList = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">        integerArrayList.add(<span class="number">1</span>);</span><br><span class="line">        integerArrayList.add(<span class="number">2</span>);</span><br><span class="line">        integerArrayList.add(<span class="number">3</span>);</span><br><span class="line">        TypeLimitForClass&lt;ArrayList&gt; typeLimitForClass01 = <span class="keyword">new</span> TypeLimitForClass&lt;&gt;();</span><br><span class="line">        typeLimitForClass01.setData(stringArrayList);</span><br><span class="line">        TypeLimitForClass&lt;ArrayList&gt; typeLimitForClass02 = <span class="keyword">new</span> TypeLimitForClass&lt;&gt;();</span><br><span class="line">        typeLimitForClass02.setData(integerArrayList);</span><br><span class="line"></span><br><span class="line">        System.out.println(getMinListSize(typeLimitForClass01.getData().size(), typeLimitForClass02.getData().size()));</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T extends Comparable&lt;T&gt;&gt; <span class="function">T <span class="title">getMinListSize</span><span class="params">(T a, T b)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> (a.compareTo(b) &lt; <span class="number">0</span>) ? a : b;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<h1 id="6-泛型中的约束和局限性"><a href="#6-泛型中的约束和局限性" class="headerlink" title="6.泛型中的约束和局限性"></a>6.泛型中的约束和局限性</h1><p>1.不能实例化泛型类<br>2.静态变量或方法不能引用泛型类型变量，但是静态泛型方法是可以的<br>3.基本类型无法作为泛型类型<br>4.无法使用instanceof关键字或==判断泛型类的类型<br>5.泛型类的原生类型与所传递的泛型无关，无论传递什么类型，原生类是一样的<br>6.泛型数组可以声明但无法实例化<br>7.泛型类不能继承Exception或者Throwable<br>8.不能捕获泛型类型限定的异常但可以将泛型限定的异常抛出</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Author：Jay On 2019/5/10 17:41</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * Description: 泛型的约束和局限性</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GenericRestrict1</span>&lt;<span class="title">T</span>&gt; </span>&#123;</span><br><span class="line">    <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">NormalClass</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> T data;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 不能实例化泛型类</span></span><br><span class="line"><span class="comment">     * Type parameter 'T' cannot be instantiated directly</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setData</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">//this.data = new T();</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 静态变量或方法不能引用泛型类型变量</span></span><br><span class="line"><span class="comment">     * 'com.jay.java.泛型.restrict.GenericRestrict1.this' cannot be referenced from a static context</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="comment">//    private static T result;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//    private static T getResult() &#123;</span></span><br><span class="line"><span class="comment">//        return result;</span></span><br><span class="line"><span class="comment">//    &#125;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 静态泛型方法是可以的</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> &lt;K&gt; <span class="function">K <span class="title">getKey</span><span class="params">(K k)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> k;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        NormalClass normalClassA = <span class="keyword">new</span> NormalClass();</span><br><span class="line">        NormalClass normalClassB = <span class="keyword">new</span> NormalClass();</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 基本类型无法作为泛型类型</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line"><span class="comment">//        GenericRestrict1&lt;int&gt; genericRestrictInt = new GenericRestrict1&lt;&gt;();</span></span><br><span class="line">        GenericRestrict1&lt;Integer&gt; genericRestrictInteger = <span class="keyword">new</span> GenericRestrict1&lt;&gt;();</span><br><span class="line">        GenericRestrict1&lt;String&gt; genericRestrictString = <span class="keyword">new</span> GenericRestrict1&lt;&gt;();</span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 无法使用instanceof关键字判断泛型类的类型</span></span><br><span class="line"><span class="comment">         * Illegal generic type for instanceof</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line"><span class="comment">//        if(genericRestrictInteger instanceof GenericRestrict1&lt;Integer&gt;)&#123;</span></span><br><span class="line"><span class="comment">//            return;</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 无法使用“==”判断两个泛型类的实例</span></span><br><span class="line"><span class="comment">         * Operator '==' cannot be applied to this two instance</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line"><span class="comment">//        if (genericRestrictInteger == genericRestrictString) &#123;</span></span><br><span class="line"><span class="comment">//            return;</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 泛型类的原生类型与所传递的泛型无关，无论传递什么类型，原生类是一样的</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        System.out.println(normalClassA == normalClassB);<span class="comment">//false</span></span><br><span class="line">        System.out.println(genericRestrictInteger == genericRestrictInteger);<span class="comment">//</span></span><br><span class="line">        System.out.println(genericRestrictInteger.getClass() == genericRestrictString.getClass()); <span class="comment">//true</span></span><br><span class="line">        System.out.println(genericRestrictInteger.getClass());<span class="comment">//com.jay.java.泛型.restrict.GenericRestrict1</span></span><br><span class="line">        System.out.println(genericRestrictString.getClass());<span class="comment">//com.jay.java.泛型.restrict.GenericRestrict1</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 泛型数组可以声明但无法实例化</span></span><br><span class="line"><span class="comment">         * Generic array creation</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        GenericRestrict1&lt;String&gt;[] genericRestrict1s;</span><br><span class="line"><span class="comment">//        genericRestrict1s = new GenericRestrict1&lt;String&gt;[10];</span></span><br><span class="line">        genericRestrict1s = <span class="keyword">new</span> GenericRestrict1[<span class="number">10</span>];</span><br><span class="line">        genericRestrict1s[<span class="number">0</span>]=genericRestrictString;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Author：Jay On 2019/5/10 18:45</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * Description: 泛型和异常</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GenericRestrict2</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="class"><span class="keyword">class</span> <span class="title">MyException</span> <span class="keyword">extends</span> <span class="title">Exception</span> </span>&#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 泛型类不能继承Exception或者Throwable</span></span><br><span class="line"><span class="comment">     * Generic class may not extend 'java.lang.Throwable'</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="comment">//    private class MyGenericException&lt;T&gt; extends Exception &#123;</span></span><br><span class="line"><span class="comment">//    &#125;</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">//    private class MyGenericThrowable&lt;T&gt; extends Throwable &#123;</span></span><br><span class="line"><span class="comment">//    &#125;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 不能捕获泛型类型限定的异常</span></span><br><span class="line"><span class="comment">     * Cannot catch type parameters</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> &lt;T extends Exception&gt; <span class="function"><span class="keyword">void</span> <span class="title">getException</span><span class="params">(T t)</span> </span>&#123;</span><br><span class="line"><span class="comment">//        try &#123;</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">//        &#125; catch (T e) &#123;</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *可以将泛型限定的异常抛出</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> &lt;T extends Throwable&gt; <span class="function"><span class="keyword">void</span> <span class="title">getException</span><span class="params">(T t)</span> <span class="keyword">throws</span> T </span>&#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line"></span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            <span class="keyword">throw</span> t;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="7-泛型类型继承规则"><a href="#7-泛型类型继承规则" class="headerlink" title="7.泛型类型继承规则"></a>7.泛型类型继承规则</h1><p>1.对于泛型参数是继承关系的泛型类之间是没有继承关系的<br>2.泛型类可以继承其它泛型类，例如: public class ArrayList<E> extends AbstractList<E><br>3.泛型类的继承关系在使用中同样会受到泛型类型的影响</E></E></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Author：Jay On 2019/5/10 19:13</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * Description: 泛型继承规则测试类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GenericInherit</span>&lt;<span class="title">T</span>&gt; </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> T data1;</span><br><span class="line">    <span class="keyword">private</span> T data2;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> T <span class="title">getData1</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> data1;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setData1</span><span class="params">(T data1)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.data1 = data1;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> T <span class="title">getData2</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> data2;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setData2</span><span class="params">(T data2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.data2 = data2;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;V&gt; <span class="function"><span class="keyword">void</span> <span class="title">setData2</span><span class="params">(GenericInherit&lt;Father&gt; data2)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"><span class="comment">//        Son 继承自 Father</span></span><br><span class="line">        Father father = <span class="keyword">new</span> Father();</span><br><span class="line">        Son son = <span class="keyword">new</span> Son();</span><br><span class="line">        GenericInherit&lt;Father&gt; fatherGenericInherit = <span class="keyword">new</span> GenericInherit&lt;&gt;();</span><br><span class="line">        GenericInherit&lt;Son&gt; sonGenericInherit = <span class="keyword">new</span> GenericInherit&lt;&gt;();</span><br><span class="line">        SubGenericInherit&lt;Father&gt; fatherSubGenericInherit = <span class="keyword">new</span> SubGenericInherit&lt;&gt;();</span><br><span class="line">        SubGenericInherit&lt;Son&gt; sonSubGenericInherit = <span class="keyword">new</span> SubGenericInherit&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 对于传递的泛型类型是继承关系的泛型类之间是没有继承关系的</span></span><br><span class="line"><span class="comment">         * GenericInherit&lt;Father&gt; 与GenericInherit&lt;Son&gt; 没有继承关系</span></span><br><span class="line"><span class="comment">         * Incompatible types.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        father = <span class="keyword">new</span> Son();</span><br><span class="line"><span class="comment">//        fatherGenericInherit=new GenericInherit&lt;Son&gt;();</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 泛型类可以继承其它泛型类，例如: public class ArrayList&lt;E&gt; extends AbstractList&lt;E&gt;</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        fatherGenericInherit=<span class="keyword">new</span> SubGenericInherit&lt;Father&gt;();</span><br><span class="line"></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         *泛型类的继承关系在使用中同样会受到泛型类型的影响</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        setData2(fatherGenericInherit);</span><br><span class="line"><span class="comment">//        setData2(sonGenericInherit);</span></span><br><span class="line">        setData2(fatherSubGenericInherit);</span><br><span class="line"><span class="comment">//        setData2(sonSubGenericInherit);</span></span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">SubGenericInherit</span>&lt;<span class="title">T</span>&gt; <span class="keyword">extends</span> <span class="title">GenericInherit</span>&lt;<span class="title">T</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<h1 id="8-通配符类型"><a href="#8-通配符类型" class="headerlink" title="8.通配符类型"></a>8.通配符类型</h1><p>1.<? extends Parent> 指定了泛型类型的上届
2.<? super Child> 指定了泛型类型的下届
3.<?> 指定了没有限制的泛型类型</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Author：Jay On 2019/5/10 19:51</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * Description: 泛型通配符测试类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GenericByWildcard</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">print</span><span class="params">(GenericClass&lt;Fruit&gt; fruitGenericClass)</span> </span>&#123;</span><br><span class="line">        System.out.println(fruitGenericClass.getData().getColor());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">use</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        GenericClass&lt;Fruit&gt; fruitGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        print(fruitGenericClass);</span><br><span class="line">        GenericClass&lt;Orange&gt; orangeGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        <span class="comment">//类型不匹配,可以使用&lt;? extends Parent&gt; 来解决</span></span><br><span class="line"><span class="comment">//        print(orangeGenericClass);</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * &lt;? extends Parent&gt; 指定了泛型类型的上届</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">printExtends</span><span class="params">(GenericClass&lt;? extends Fruit&gt; genericClass)</span> </span>&#123;</span><br><span class="line">        System.out.println(genericClass.getData().getColor());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">useExtend</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        GenericClass&lt;Fruit&gt; fruitGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        printExtends(fruitGenericClass);</span><br><span class="line">        GenericClass&lt;Orange&gt; orangeGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        printExtends(orangeGenericClass);</span><br><span class="line"></span><br><span class="line">        GenericClass&lt;Food&gt; foodGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        <span class="comment">//Food是Fruit的父类，超过了泛型上届范围，类型不匹配</span></span><br><span class="line"><span class="comment">//        printExtends(foodGenericClass);</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//表示GenericClass的类型参数的上届是Fruit</span></span><br><span class="line">        GenericClass&lt;? extends Fruit&gt; extendFruitGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        Apple apple = <span class="keyword">new</span> Apple();</span><br><span class="line">        Fruit fruit = <span class="keyword">new</span> Fruit();</span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">         * 道理很简单，？ extends X  表示类型的上界，类型参数是X的子类，那么可以肯定的说，</span></span><br><span class="line"><span class="comment">         * get方法返回的一定是个X（不管是X或者X的子类）编译器是可以确定知道的。</span></span><br><span class="line"><span class="comment">         * 但是set方法只知道传入的是个X，至于具体是X的那个子类，不知道。</span></span><br><span class="line"><span class="comment">         * 总结：主要用于安全地访问数据，可以访问X及其子类型，并且不能写入非null的数据。</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line"><span class="comment">//        extendFruitGenericClass.setData(apple);</span></span><br><span class="line"><span class="comment">//        extendFruitGenericClass.setData(fruit);</span></span><br><span class="line"></span><br><span class="line">        fruit = extendFruitGenericClass.getData();</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * &lt;? super Child&gt; 指定了泛型类型的下届</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">printSuper</span><span class="params">(GenericClass&lt;? <span class="keyword">super</span> Apple&gt; genericClass)</span> </span>&#123;</span><br><span class="line">        System.out.println(genericClass.getData());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">useSuper</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        GenericClass&lt;Food&gt; foodGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        printSuper(foodGenericClass);</span><br><span class="line"></span><br><span class="line">        GenericClass&lt;Fruit&gt; fruitGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        printSuper(fruitGenericClass);</span><br><span class="line"></span><br><span class="line">        GenericClass&lt;Apple&gt; appleGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        printSuper(appleGenericClass);</span><br><span class="line"></span><br><span class="line">        GenericClass&lt;HongFuShiApple&gt; hongFuShiAppleGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        <span class="comment">// HongFuShiApple 是Apple的子类，达不到泛型下届，类型不匹配</span></span><br><span class="line"><span class="comment">//        printSuper(hongFuShiAppleGenericClass);</span></span><br><span class="line"></span><br><span class="line">        GenericClass&lt;Orange&gt; orangeGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        <span class="comment">// Orange和Apple是兄弟关系，没有继承关系，类型不匹配</span></span><br><span class="line"><span class="comment">//        printSuper(orangeGenericClass);</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//表示GenericClass的类型参数的下界是Apple</span></span><br><span class="line">        GenericClass&lt;? <span class="keyword">super</span> Apple&gt; supperAppleGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        supperAppleGenericClass.setData(<span class="keyword">new</span> Apple());</span><br><span class="line">        supperAppleGenericClass.setData(<span class="keyword">new</span> HongFuShiApple());</span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">         * ？ super  X  表示类型的下界，类型参数是X的超类（包括X本身），</span></span><br><span class="line"><span class="comment">         * 那么可以肯定的说，get方法返回的一定是个X的超类，那么到底是哪个超类？不知道，</span></span><br><span class="line"><span class="comment">         * 但是可以肯定的说，Object一定是它的超类，所以get方法返回Object。</span></span><br><span class="line"><span class="comment">         * 编译器是可以确定知道的。对于set方法来说，编译器不知道它需要的确切类型，但是X和X的子类可以安全的转型为X。</span></span><br><span class="line"><span class="comment">         * 总结：主要用于安全地写入数据，可以写入X及其子类型。</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line"><span class="comment">//        supperAppleGenericClass.setData(new Fruit());</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">//get方法只会返回一个Object类型的值。</span></span><br><span class="line">        Object data = supperAppleGenericClass.getData();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * &lt;?&gt; 指定了没有限定的通配符</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">printNonLimit</span><span class="params">(GenericClass&lt;?&gt; genericClass)</span> </span>&#123;</span><br><span class="line">        System.out.println(genericClass.getData());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">useNonLimit</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        GenericClass&lt;Food&gt; foodGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        printNonLimit(foodGenericClass);</span><br><span class="line">        GenericClass&lt;Fruit&gt; fruitGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        printNonLimit(fruitGenericClass);</span><br><span class="line">        GenericClass&lt;Apple&gt; appleGenericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        printNonLimit(appleGenericClass);</span><br><span class="line"></span><br><span class="line">        GenericClass&lt;?&gt; genericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        <span class="comment">//setData 方法不能被调用， 甚至不能用 Object 调用；</span></span><br><span class="line"><span class="comment">//        genericClass.setData(foodGenericClass);</span></span><br><span class="line"><span class="comment">//        genericClass.setData(new Object());</span></span><br><span class="line">        <span class="comment">//返回值只能赋给 Object</span></span><br><span class="line">        Object object = genericClass.getData();</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="9-获取泛型的参数类型"><a href="#9-获取泛型的参数类型" class="headerlink" title="9.获取泛型的参数类型"></a>9.获取泛型的参数类型</h1><p>Type是什么<br>这里的Type指java.lang.reflect.Type, 是Java中所有类型的公共高级接口, 代表了Java中的所有类型. Type体系中类型的包括：数组类型(GenericArrayType)、参数化类型(ParameterizedType)、类型变量(TypeVariable)、通配符类型(WildcardType)、原始类型(Class)、基本类型(Class), 以上这些类型都实现Type接口.</p>
<p>参数化类型,就是我们平常所用到的泛型List、Map；<br>数组类型,并不是我们工作中所使用的数组String[] 、byte[]，而是带有泛型的数组，即T[] ；<br>通配符类型, 指的是&lt;?&gt;, &lt;? extends T&gt;等等<br>原始类型, 不仅仅包含我们平常所指的类，还包括枚举、数组、注解等；<br>基本类型, 也就是我们所说的java的基本类型，即int,float,double等</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">ParameterizedType</span> <span class="keyword">extends</span> <span class="title">Type</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 返回确切的泛型参数, 如Map&lt;String, Integer&gt;返回[String, Integer]</span></span><br><span class="line">    Type[] getActualTypeArguments();</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//返回当前class或interface声明的类型, 如List&lt;?&gt;返回List</span></span><br><span class="line">    <span class="function">Type <span class="title">getRawType</span><span class="params">()</span></span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//返回所属类型. 如,当前类型为O&lt;T&gt;.I&lt;S&gt;, 则返回O&lt;T&gt;. 顶级类型将返回null </span></span><br><span class="line">    <span class="function">Type <span class="title">getOwnerType</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Author：Jay On 2019/5/11 22:41</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * Description: 获取泛型类型测试类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GenericType</span>&lt;<span class="title">T</span>&gt; </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> T data;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> T <span class="title">getData</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> data;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setData</span><span class="params">(T data)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.data = data;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        GenericType&lt;String&gt; genericType = <span class="keyword">new</span> GenericType&lt;String&gt;() &#123;&#125;;</span><br><span class="line">        Type superclass = genericType.getClass().getGenericSuperclass();</span><br><span class="line">        <span class="comment">//getActualTypeArguments 返回确切的泛型参数, 如Map&lt;String, Integer&gt;返回[String, Integer]</span></span><br><span class="line">        Type type = ((ParameterizedType) superclass).getActualTypeArguments()[<span class="number">0</span>]; </span><br><span class="line">        System.out.println(type);<span class="comment">//class java.lang.String</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="10-虚拟机是如何实现泛型的"><a href="#10-虚拟机是如何实现泛型的" class="headerlink" title="10.虚拟机是如何实现泛型的"></a>10.虚拟机是如何实现泛型的</h1><p>Java泛型是Java1.5之后才引入的，为了向下兼容。Java采用了C++完全不同的实现思想。Java中的泛型更多的看起来像是编译期用的<br>Java中泛型在运行期是不可见的，会被擦除为它的上级类型。如果是没有限定的泛型参数类型，就会被替换为Object.</p>
<p>GenericClass<String> stringGenericClass=new GenericClass&lt;&gt;();<br>GenericClass<Integer> integerGenericClass=new GenericClass&lt;&gt;();<br>C++中GenericClass<String>和GenericClass<Integer>是两个不同的类型<br>Java进行了类型擦除之后统一改为GenericClass<Object></Object></Integer></String></Integer></String></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Author：Jay On 2019/5/11 16:11</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * Description:泛型原理测试类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GenericTheory</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Map&lt;String, String&gt; map = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line">        map.put(<span class="string">"Key"</span>, <span class="string">"Value"</span>);</span><br><span class="line">        System.out.println(map.get(<span class="string">"Key"</span>));</span><br><span class="line">        GenericClass&lt;String, String&gt; genericClass = <span class="keyword">new</span> GenericClass&lt;&gt;();</span><br><span class="line">        genericClass.put(<span class="string">"Key"</span>, <span class="string">"Value"</span>);</span><br><span class="line">        System.out.println(genericClass.get(<span class="string">"Key"</span>));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">GenericClass</span>&lt;<span class="title">K</span>, <span class="title">V</span>&gt; </span>&#123;</span><br><span class="line">        <span class="keyword">private</span> K key;</span><br><span class="line">        <span class="keyword">private</span> V value;</span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">put</span><span class="params">(K key, V value)</span> </span>&#123;</span><br><span class="line">            <span class="keyword">this</span>.key = key;</span><br><span class="line">            <span class="keyword">this</span>.value = value;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">public</span> V <span class="title">get</span><span class="params">(V key)</span> </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> value;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 类型擦除后GenericClass2&lt;Object&gt;</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> &lt;T&gt;</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">private</span> <span class="class"><span class="keyword">class</span> <span class="title">GenericClass2</span>&lt;<span class="title">T</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 类型擦除后GenericClass3&lt;ArrayList&gt;</span></span><br><span class="line"><span class="comment">     * 当使用到Serializable时会将相应代码强制转换为Serializable</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> &lt;T&gt;</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">private</span> <span class="class"><span class="keyword">class</span> <span class="title">GenericClass3</span>&lt;<span class="title">T</span> <span class="keyword">extends</span> <span class="title">ArrayList</span> &amp; <span class="title">Serializable</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>对应的字节码文件</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">       Map&lt;String, String&gt; map = <span class="keyword">new</span> HashMap();</span><br><span class="line">       map.put(<span class="string">"Key"</span>, <span class="string">"Value"</span>);</span><br><span class="line">       System.out.println((String)map.get(<span class="string">"Key"</span>));</span><br><span class="line">       GenericTheory.GenericClass&lt;String, String&gt; genericClass = <span class="keyword">new</span> GenericTheory.GenericClass();</span><br><span class="line">       genericClass.put(<span class="string">"Key"</span>, <span class="string">"Value"</span>);</span><br><span class="line">       System.out.println((String)genericClass.get(<span class="string">"Key"</span>));</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>
                    
                    <!-- Tags Bottom -->
                    
                        <div class="tags-container-bottom">
                            <i class="fa fa-tag pr3 text-main-color"></i><a class="fw3 ph1 dib" href="/tags/java/">#java</a>
                        </div>
                    

                    <!-- Comments -->
                    



                </div>
                <div class="fl w-100 w-30-l center fw3 lh-copy pl4-ns tl black-50">
                    
                    <hr class="dn-l mw4 black-50 mt5" />
                    
                    <!-- Widget 1: About -->
                    <div class="mt5 mt0-l">
    <article class="dt db-l mw8 mw8-m mw5-ns center ml0-l bg-white mv3">
        <div class="dn dtc-m db-l v-mid tc pr4 pr0-l" style="min-width: 6rem;">
            <img src="https://avatars0.githubusercontent.com/u/47167745?s=460&v=4" class="mb4-l br-100 h3 w3 h4-l w4-l dib" title="ZZZXXXCCCWXY999">
        </div>
        <div class="dtc db-l v-mid lh-copy measure center f6 black-50 tj">
            我是ZZZXXXCCCWXY999，这是我的博客。<br>没错，看我的ID就能知道我是一个巨星。<br>我会在博客里写一些我在专业方面的分享。
        </div>
    </article>
</div>

                    <hr class="dn-l mw4 black-50 mt5" />
                    
                    <!-- Widget 2: Categories -->
                    
                        <div class="mt5 tc tl-l">
    <h3>分类</h3>
    
        <p>
            <a href="/categories/java/">java</a>
        </p>
    
</div>


                        <hr class="dn-l mw4 black-50 mt5" />
                    

                    <!-- Widget 3: Recent Posts -->
                    <div class="mt5 tc tl-l">
    <h3>近期文章</h3>
    
        <p>
            <a href="/2020/04/01/%E6%B3%9B%E5%9E%8B%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86/">泛型相关知识</a>
        </p>
    
        <p>
            <a href="/2020/03/14/String-s-abc-%E5%92%8C-String-s-new-String-abc-%E7%9A%84%E5%8C%BA%E5%88%AB/">String s=&#34;abc&#34; 和 String s=new String(&#34;abc&#34;)的区别</a>
        </p>
    
        <p>
            <a href="/2020/03/11/%E5%B0%8F%E7%B1%B3java%E5%AE%9E%E4%B9%A0%E9%9D%A2%E7%BB%8F/">小米java实习面经</a>
        </p>
    
        <p>
            <a href="/2020/03/11/Spring%E5%88%9D%E5%A7%8B%E5%8C%96%E7%9A%84%E6%AD%A5%E9%AA%A4/">Spring初始化的步骤</a>
        </p>
    
        <p>
            <a href="/2020/03/11/%E5%85%B3%E4%BA%8E%E4%B8%89%E5%A4%A7IO%E7%9A%84%E7%90%86%E8%A7%A3-AIO-BIO-NIO/">关于三大IO的理解:BIO,NIO,AIO</a>
        </p>
    
</div>
                </div>
            </div>
        </div>
    </div>
</div>


<!-- Footer -->
<div class="bg-1 ph2 ph5-ns pv5">
    <div class="mv8">
        <div class="center tc">
            
                <div class="dib mh3">
                    <a class="f3 f2-ns white dim" href="https://twitter.com/?lang=en" target="_blank">
                        <i class="fa fa-twitter"></i>
                    </a>
                </div>
            
                <div class="dib mh3">
                    <a class="f3 f2-ns white dim" href="https://www.facebook.com/" target="_blank">
                        <i class="fa fa-facebook"></i>
                    </a>
                </div>
            
                <div class="dib mh3">
                    <a class="f3 f2-ns white dim" href="https://dribbble.com/" target="_blank">
                        <i class="fa fa-dribbble"></i>
                    </a>
                </div>
            
                <div class="dib mh3">
                    <a class="f3 f2-ns white dim" href="https://github.com/ZZZXXXCCCWXY999/" target="_blank">
                        <i class="fa fa-github"></i>
                    </a>
                </div>
            
                <div class="dib mh3">
                    <a class="f3 f2-ns white dim" href="https://plus.google.com/" target="_blank">
                        <i class="fa fa-google-plus"></i>
                    </a>
                </div>
            
                <div class="dib mh3">
                    <a class="f3 f2-ns white dim" href="https://www.behance.net/" target="_blank">
                        <i class="fa fa-behance"></i>
                    </a>
                </div>
            
                <div class="dib mh3">
                    <a class="f3 f2-ns white dim" href="https://500px.com/" target="_blank">
                        <i class="fa fa-500px"></i>
                    </a>
                </div>
            
                <div class="dib mh3">
                    <a class="f3 f2-ns white dim" href="mailto:zzzxxxcccwxy999@gmail.com" target="_blank">
                        <i class="fa fa-envelope"></i>
                    </a>
                </div>
            
                <div class="dib mh3">
                    <a class="f3 f2-ns white dim" href="/#" target="_blank">
                        <i class="fa fa-rss"></i>
                    </a>
                </div>
            
        </div>
        <div class="f6 f5-ns center tc white pt5 fw3">
            2020 KTG知识技术小组 | ZZZXXXCCCWXY999 | 真是一个巨星
        </div>
        
            <!-- 不蒜子统计 -->
            <div style="text-align:center;color:#FFFFFF">
            <span id="busuanzi_container_site_pv">
                本站总访问量<span id="busuanzi_value_site_pv"></span>次
        </span>
                <span class="post-meta-divider">|</span>
<!--                <span id="busuanzi_container_site_uv" style='display:none'>-->
<!--                本站访客数<span id="busuanzi_value_site_uv"></span>人-->
<!--        </span>-->
            </div>
<!--            <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>-->
            <script async src="/js/busuanzi.pure.mini.js"></script>
        

    </div>
</div>

<!-- After Footer -->
<!-- Disqus Comments -->



</body>

</html>